﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ValidationFramework.Configuration.Reflection;
using ValidationFramework.Reflection;
using ValidationFramework.Tests.TestHelpers;

namespace ValidationFramework.Tests.Configuration.Reflection
{
	public class RuleAttributeScannerTests
	{
		#region Test Model
		public class Person
		{
			public string FistName { get; set; }
			public string LastName { get; set; }
		}
		public class Student : Person, IDoSchool
		{
			public int Age { get; set; }

			// IDoSchool members
			[AlwaysFail(Id = "2")]
			[AlwaysFail(Id = "1")]
			public int GPA { get; set; }
		}
		public class Freshman : Student
		{
			[AlwaysFail]
			public string Major { get; set; }
		}
		public interface IDoSchool
		{
			[AlwaysFail(Id = "1")]
			int GPA { get; set; }
		}
		#endregion

		[TestFixture]
		public class Construction
		{
			[Test]
			public void Should_Default_Ancestry_Flag_Correctly()
			{
				var scanner = new RuleAttributeScanner(null, null, null);

				Assert.IsTrue(scanner.ScanPropertyAncestry);
				Assert.IsTrue(scanner.ScanParameterAncestry);
			}
		}

		[TestFixture]
		public class ScanPropertyTests
		{
			[Test]
			public void Should_Detect_Only_Attributes_Defined_On_Class_When_Anestry_Flag_Is_False()
			{
				// arrange
				var typeRepo = new TypePolicyRepository();
				var scanner = new RuleAttributeScanner(typeRepo, null, new ReflectionCache());
				scanner.ScanPropertyAncestry = false;
				var property = typeof(Freshman).GetProperty("Major");

				// act
				scanner.ScanProperty(property);

				// Assert
				var propertyPolicy = typeRepo.GetPropertyPolicy(property.ToPropertyKey());
				Assert.AreEqual(1, propertyPolicy.RuleCount);				
			}

			[Test]
			public void Should_Detect_And_Add_Rules_From_Ancestry_When_Enabled()
			{
				// arrange
				var typeRepo = new TypePolicyRepository();
				var scanner = new RuleAttributeScanner(typeRepo, null, new ReflectionCache());
				var property = typeof(Freshman).GetProperty("GPA");

				// act
				scanner.ScanProperty(property);

				// Assert
				var propertyPolicy = typeRepo.GetPropertyPolicy(property.ToPropertyKey());
				Assert.AreEqual(2, propertyPolicy.RuleCount);
			}
		}
	}
}
